package com.wzh.codegen.biz.util;

import com.wzh.codegen.biz.domain.dto.CodegenTableDTO;
import com.wzh.common.general.exception.CustomerException;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * 代码生成工具类
 *
 * @author wzh
 * @since 2024-01-01
 */
@Slf4j
public class CodegenUtils {

    /**
     * 首字母大写
     */
    public static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    /**
     * 首字母小写
     */
    public static String uncapitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toLowerCase() + str.substring(1);
    }

    /**
     * 下划线转驼峰
     */
    public static String toCamelCase(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }

        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = false;

        for (char c : str.toCharArray()) {
            if (c == '_' || c == '-') {
                capitalizeNext = true;
            } else {
                if (capitalizeNext) {
                    result.append(Character.toUpperCase(c));
                    capitalizeNext = false;
                } else {
                    result.append(Character.toLowerCase(c));
                }
            }
        }

        return result.toString();
    }

    /**
     * 驼峰转下划线
     */
    public static String toUnderlineCase(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }

        StringBuilder result = new StringBuilder();

        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (Character.isUpperCase(c)) {
                if (i > 0) {
                    result.append('_');
                }
                result.append(Character.toLowerCase(c));
            } else {
                result.append(c);
            }
        }

        return result.toString();
    }

    /**
     * 获取包路径
     */
    public static String getPackagePath(String packageName) {
        if (packageName == null || packageName.isEmpty()) {
            return "";
        }
        return packageName.replace(".", "/");
    }

    /**
     * 获取类名（不含包名）
     */
    public static String getClassName(String fullClassName) {
        if (fullClassName == null || fullClassName.isEmpty()) {
            return "";
        }

        int lastDotIndex = fullClassName.lastIndexOf('.');
        if (lastDotIndex >= 0) {
            return fullClassName.substring(lastDotIndex + 1);
        }

        return fullClassName;
    }

    /**
     * 获取包名（不含类名）
     */
    public static String getPackageName(String fullClassName) {
        if (fullClassName == null || fullClassName.isEmpty()) {
            return "";
        }

        int lastDotIndex = fullClassName.lastIndexOf('.');
        if (lastDotIndex >= 0) {
            return fullClassName.substring(0, lastDotIndex);
        }

        return "";
    }

    /**
     * 生成getter方法名
     */
    public static String getGetterMethodName(String fieldName, String fieldType) {
        if (fieldName == null || fieldName.isEmpty()) {
            return "";
        }

        String prefix = "boolean".equals(fieldType) || "Boolean".equals(fieldType) ? "is" : "get";
        return prefix + capitalize(fieldName);
    }

    /**
     * 生成setter方法名
     */
    public static String getSetterMethodName(String fieldName) {
        if (fieldName == null || fieldName.isEmpty()) {
            return "";
        }

        return "set" + capitalize(fieldName);
    }

    /**
     * 检查是否为基本数据类型
     */
    public static boolean isPrimitiveType(String javaType) {
        return "int".equals(javaType) || "long".equals(javaType) || "double".equals(javaType) ||
                "float".equals(javaType) || "boolean".equals(javaType) || "byte".equals(javaType) ||
                "short".equals(javaType) || "char".equals(javaType);
    }

    /**
     * 检查是否为包装类型
     */
    public static boolean isWrapperType(String javaType) {
        return "Integer".equals(javaType) || "Long".equals(javaType) || "Double".equals(javaType) ||
                "Float".equals(javaType) || "Boolean".equals(javaType) || "Byte".equals(javaType) ||
                "Short".equals(javaType) || "Character".equals(javaType);
    }

    /**
     * 检查是否为字符串类型
     */
    public static boolean isStringType(String javaType) {
        return "String".equals(javaType);
    }

    /**
     * 检查是否为日期类型
     */
    public static boolean isDateType(String javaType) {
        return "Date".equals(javaType) || "LocalDate".equals(javaType) ||
                "LocalTime".equals(javaType) || "LocalDateTime".equals(javaType) ||
                "Timestamp".equals(javaType);
    }

    /**
     * 检查是否为数字类型
     */
    public static boolean isNumberType(String javaType) {
        return "Integer".equals(javaType) || "Long".equals(javaType) || "Double".equals(javaType) ||
                "Float".equals(javaType) || "BigDecimal".equals(javaType) || "BigInteger".equals(javaType) ||
                "int".equals(javaType) || "long".equals(javaType) || "double".equals(javaType) ||
                "float".equals(javaType);
    }

    /**
     * 获取默认值
     */
    public static String getDefaultValue(String javaType) {
        if (isPrimitiveType(javaType)) {
            return switch (javaType) {
                case "boolean" -> "false";
                case "char" -> "'\\0'";
                default -> "0";
            };
        }
        return "null";
    }

    /**
     * 生成导入语句
     */
    public static String generateImports(List<String> javaTypes) {
        StringBuilder imports = new StringBuilder();

        for (String javaType : javaTypes) {
            if (needsImport(javaType)) {
                imports.append("import ").append(getFullClassName(javaType)).append(";\n");
            }
        }

        return imports.toString();
    }

    /**
     * 检查是否需要导入
     */
    private static boolean needsImport(String javaType) {
        // 基本类型和java.lang包下的类不需要导入
        return !isPrimitiveType(javaType) && !javaType.startsWith("java.lang.") &&
                !"String".equals(javaType) && !"Object".equals(javaType);
    }

    /**
     * 获取完整类名
     */
    private static String getFullClassName(String javaType) {
        return switch (javaType) {
            case "BigDecimal" -> "java.math.BigDecimal";
            case "BigInteger" -> "java.math.BigInteger";
            case "Date" -> "java.util.Date";
            case "LocalDate" -> "java.time.LocalDate";
            case "LocalTime" -> "java.time.LocalTime";
            case "LocalDateTime" -> "java.time.LocalDateTime";
            case "Timestamp" -> "java.sql.Timestamp";
            default -> javaType;
        };
    }

    /**
     * 同步生成的代码
     */
    public static void syncGeneratedCode(CodegenTableDTO dto, List<Map<String, Object>> columns) {
        try {
            // 注意：此方法主要用于代码同步，实际的代码生成和写入逻辑已在CodegenServiceImpl.generateTable中实现
            // 这里可以添加额外的同步逻辑，比如版本控制、备份等
            log.info("代码同步完成: {}, 字段数量: {}, 生成路径: {}", dto.getEntityName(), columns.size(), dto.getGeneratePath());
        } catch (Exception e) {
            log.error("同步代码失败", e);
            throw new CustomerException("同步代码失败: " + e.getMessage());
        }
    }

    /**
     * 验证Java标识符
     */
    public static boolean isValidJavaIdentifier(String identifier) {
        if (identifier == null || identifier.isEmpty()) {
            return false;
        }

        if (!Character.isJavaIdentifierStart(identifier.charAt(0))) {
            return false;
        }

        for (int i = 1; i < identifier.length(); i++) {
            if (!Character.isJavaIdentifierPart(identifier.charAt(i))) {
                return false;
            }
        }

        return true;
    }

    /**
     * 验证包名
     */
    public static boolean isValidPackageName(String packageName) {
        if (packageName == null || packageName.isEmpty()) {
            return false;
        }

        String[] parts = packageName.split("\\.");
        for (String part : parts) {
            if (!isValidJavaIdentifier(part)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 生成文件路径
     */
    public static String generateFilePath(String basePath, String packageName, String fileName) {
        StringBuilder path = new StringBuilder();

        if (basePath != null && !basePath.isEmpty()) {
            path.append(basePath);
            if (!basePath.endsWith("/")) {
                path.append("/");
            }
        }

        if (packageName != null && !packageName.isEmpty()) {
            path.append(packageName.replace(".", "/"));
            path.append("/");
        }

        path.append(fileName);

        return path.toString();
    }

}